// GrandiaX Mana Egg Table Generator.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "GrandiaX Mana Egg Table Generator.h"

#include "GrandiaX Mana Egg Table Generator Doc.h"
#include "GrandiaX Mana Egg Table Generator View.h"
#include "MainFrm.h"

#include <MMSystem.h>

#include "selfupdate.h"


#define VERSION_CODE 17
#define VERSION_TEXT L"2.3.1"


#pragma warning(disable : 4996)

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXManaEggTableGeneratorApp

BEGIN_MESSAGE_MAP(CGrandiaXManaEggTableGeneratorApp, CWinApp)
    //{{AFX_MSG_MAP(CGrandiaXManaEggTableGeneratorApp)
    ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
    ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
    //}}AFX_MSG_MAP
    // Standard file based document commands
    ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

void error(LPSTR lpszFunction) 
{ 
    LPVOID lpMsgBuf;
    FormatMessage( 
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM | 
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        GetLastError(),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
        (LPTSTR) &lpMsgBuf,
        0,
        NULL 
        );
    // Process any inserts in lpMsgBuf.
    // ...
    // Display the string.
    MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
    // Free the buffer.
    LocalFree( lpMsgBuf );
} 

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXManaEggTableGeneratorApp construction


CGrandiaXManaEggTableGeneratorApp::CGrandiaXManaEggTableGeneratorApp()
{
    int ReqRes[] = {
        IDR_ORIGINAL_MANAEGGS, IDR_ORIGINAL_MAGICS, IDR_ORIGINAL_EFFECTS,
        IDR_SPECIAL_HEADER, IDR_SPECIAL_DEFINITION, IDR_SPECIAL_DETAIL,
        IDR_COMBI_HEADER, IDR_COMBI_DEFINITION, IDR_COMBI_DETAIL,
        IDR_MAGIC_HEADER, IDR_MOVE_SKILLUP
    };

    void* Storages[] = {&ManaEggsRom, &MagicsRom, &EffectsRom,
            &SpecialHdrRom, &SpecialDefRom, &SpecialDetailRom,
            &CombiHdrRom, &CombiDefRom, &CombiDetailRom,
            &MagicHdrRom, &MoveSkillUpRom
    };

    for (int r=0;r<sizeof(ReqRes)/sizeof(ReqRes[0]);r++)
    {
        HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(ReqRes[r]), _T("BINARY"));

        if (!hRes)
            error("FindResource");

        HGLOBAL hGlobal = LoadResource(NULL, hRes);

        if (!hGlobal)
            error("LoadResource");

        *((void**)(Storages[r])) = LockResource(hGlobal);

        if (!Storages[r])
            error("LockResource");
    }
}

const MANAEGG_INTERNAL_TABLE*
    CGrandiaXManaEggTableGeneratorApp::GetOriginalMagicData(int Egg) const
{
    int EggFix = Egg;
    if (Egg > 27)
        EggFix += 2;
    return &ManaEggsRom[EggFix]; 
}

const MAGIC_INTERNAL_DATA*
    CGrandiaXManaEggTableGeneratorApp::GetOriginalMagicDesc(int Magic) const
{
    return &MagicsRom[Magic];
}

const EFFECT_INTERNAL_DATA*
    CGrandiaXManaEggTableGeneratorApp::GetOriginalEffect(int Magic) const
{
    return &EffectsRom[Magic];
}

const SPECIAL_HEADER*
    CGrandiaXManaEggTableGeneratorApp::GetOriginalMagicHeader(int Magic) const
{
    return &MagicHdrRom[Magic];
}

void CGrandiaXManaEggTableGeneratorApp::GetOriginalSpecialData(
    const SPECIAL_HEADER** Header, const SPECIAL_DEF** Def,
    const SPECIAL_DETAIL** Details) const
{
    *Header = SpecialHdrRom;
    *Def = SpecialDefRom;
    *Details = SpecialDetailRom;
}

void CGrandiaXManaEggTableGeneratorApp::GetOriginalCombiData(
     const SPECIAL_HEADER** Header, const SPECIAL_DEF** Def,
     const SPECIAL_DETAIL** Details) const
{
    *Header = CombiHdrRom;
    *Def = CombiDefRom;
    *Details = CombiDetailRom;
}

const MOVE_SKILLUP* CGrandiaXManaEggTableGeneratorApp::
    GetOriginalMoveLevelUpData(int Move) const
{
    return &MoveSkillUpRom[Move];
}



/////////////////////////////////////////////////////////////////////////////
// The one and only CGrandiaXManaEggTableGeneratorApp object

CGrandiaXManaEggTableGeneratorApp theApp;



/////////////////////////////////////////////////////////////////////////////
// CGrandiaXManaEggTableGeneratorApp initialization

BOOL CGrandiaXManaEggTableGeneratorApp::InitInstance()
{
    AfxEnableControlContainer();

    // Standard initialization
    // If you are not using these features and wish to reduce the size
    //  of your final executable, you should remove from the following
    //  the specific initialization routines you do not need.

#ifdef _AFXDLL
    Enable3dControls();			// Call this when using MFC in a shared DLL
#else
    Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

    // Change the registry key under which our settings are stored.
    // TODO: You should modify this string to be something appropriate
    // such as the name of your company or organization.
    SetRegistryKey(_T("Local AppWizard-Generated Applications"));

    LoadStdProfileSettings();  // Load standard INI file options (including MRU)

    // Register the application's document templates.  Document templates
    //  serve as the connection between documents, frame windows and views.

    CSingleDocTemplate* pDocTemplate;
    pDocTemplate = new CSingleDocTemplate(
        IDR_MAINFRAME,
        RUNTIME_CLASS(CGrandiaXManaEggTableGeneratorDoc),
        RUNTIME_CLASS(CMainFrame),       // main SDI frame window
        RUNTIME_CLASS(CGrandiaXManaEggTableGeneratorView));

    AddDocTemplate(pDocTemplate);

    // Parse command line for standard shell commands, DDE, file open
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);

    // Dispatch commands specified on the command line
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;

    // The one and only window has been initialized, so show and update it.
    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();

    CheckUpdate(NULL);

    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

    // Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

    // Implementation
protected:
    //{{AFX_MSG(CAboutDlg)
    afx_msg void OnCheckUpdate();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
    ON_BN_CLICKED(IDC_CHECK_UPDATE, OnCheckUpdate)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

// App command to run the dialog
void CGrandiaXManaEggTableGeneratorApp::OnAppAbout()
{
    CAboutDlg aboutDlg;
    aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CGrandiaXManaEggTableGeneratorApp message handlers


void CGrandiaXManaEggTableGeneratorApp::OnFileOpen() 
{ 
    static TCHAR szFilter[] = TEXT("GrandiaX Dump (*.gxd)|*.gxd|PS2 Enulator Patch (*.pnach) |*.pnach||");

    TCHAR szFileName[_MAX_PATH];

    lstrcpy(szFileName, TEXT("958A6461.gxd"));

    CFileDialog dlgFile(TRUE, TEXT(".gxd"), szFileName,
        OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, NULL, 0);	

    if (dlgFile.DoModal())
    {
        OpenDocumentFile(dlgFile.GetPathName());
    }

}

#define SERVER_ROOT L"https://dl.dropboxusercontent.com/u/1890357/software/gxe/"

#define UPDATE_FILENAME L"gxe-" VERSION_TEXT L".exe"


static void OnUpdateNotFound(SELFUPDATEPARAM* Param)
{
    if (IDYES==MessageBoxA(NULL, "You are using the latest verion!"
        "\nView the User Manual Now?\n"
        , "Notice", MB_ICONQUESTION|MB_YESNO))
    {
         ShellExecuteW(NULL, L"open", Param->Homepage, NULL, NULL, SW_NORMAL);
    }
}


void CGrandiaXManaEggTableGeneratorApp::CheckUpdate(SELFUPDATE_CALLBACK OnUpdateNotFound)
{
    SELFUPDATEPARAM sup;
    memset(&sup, 0, sizeof(sup));

    sup.InfoUrl = SERVER_ROOT L"updateinfox.sui";
    sup.AppName = L"gxe.exe";

    wcscpy(sup.Homepage, 
        L"http://code.google.com/p/grandiax-mana-egg-table-generator/wiki/GrandiaXManaEggTableGenerator");
    wcscpy(sup.UpdateFilePath, SERVER_ROOT);
    wcscpy(sup.UpdateFileName, UPDATE_FILENAME);
    wcscpy(sup.UpdateLogFileName, 
        L"http://code.google.com/p/grandiax-mana-egg-table-generator/wiki/GrandiaXManaEggTableGenerator?wl=zh-Hans");

    wcscpy(sup.DownloadPage, 
        L"http://code.google.com/p/grandiax-mana-egg-table-generator/downloads/list");
    
    sup.VersionCode = VERSION_CODE;

    sup.OnUpdateNotFound = OnUpdateNotFound;

    SelfUpdate(&sup);

}



void CAboutDlg::OnCheckUpdate() 
{
    ((CGrandiaXManaEggTableGeneratorApp*)AfxGetApp())->CheckUpdate(OnUpdateNotFound);
}


BOOL CToolTipCtrlEx::Addt(HWND hWnd, LPCTSTR str)
{
	TOOLINFO ti;
	memset(&ti,0,sizeof(TOOLINFO));
	ti.cbSize=sizeof(TOOLINFO);
	ti.lpszText=(LPSTR)str;
	ti.uFlags=TTF_IDISHWND|TTF_SUBCLASS|TTF_PARSELINKS;
	ti.uId=(UINT)hWnd;
	ti.hwnd=GetOwner()->GetSafeHwnd();
	return (BOOL)SendMessage(TTM_ADDTOOL,0,(LPARAM)&ti);
}

int EditToInt(CEdit &Edit)
{
    CHAR EditText[256];

    Edit.GetWindowText(EditText, 256);

    return _ttoi(EditText);
}


CReplaceDlg::CReplaceDlg() : CDialog(CReplaceDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
}


BEGIN_MESSAGE_MAP(CReplaceDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
    ON_BN_CLICKED(IDC_REPLACE, OnReplace)
    //}}AFX_MSG_MAP
//    ON_WM_CREATE()
END_MESSAGE_MAP()

void CReplaceDlg::OnReplace() 
{
    Value = GetDlgItemInt(IDC_NEWVALUE);
    EndDialog(IDOK);
}

void CReplaceDlg::SetValue(int Value) 
{
    this->Value = Value;
}

int CReplaceDlg::GetValue() 
{
    return Value;
}


BOOL CReplaceDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    SetDlgItemInt(IDC_NEWVALUE, Value);

    return FALSE;  // return TRUE unless you set the focus to a control

}
